package edu.protbioinfo;

import org.apache.commons.lang.ArrayUtils;

import edu.protbioinfo.Utils.Pair;



public interface SequenceAligner {
	public static final double NEGATIVE_INFINITY =  Double.NEGATIVE_INFINITY;
		
	public static enum Direction{
		Stop, Diagonal, Left, Up;

		public String toString() {
			return "" + name().charAt(0);
		}
		
		
	}

	public SequenceAlignment align(Pair<String, String> source);

	public static class ScoreMatrix extends LabeledMatrix<ScoreMatrix.CellValue>{

		public ScoreMatrix(Pair<String, String> sequencePair) {
			super(ArrayUtils.addAll(new char[]{' '}, sequencePair.second().toCharArray()),  
				  ArrayUtils.addAll(new char[]{' '}, sequencePair.first().toCharArray()));
		}

//		public ScoreMatrix(char[] rowLabels, char[] colLabels) {
//			super(rowLabels, colLabels);
//
//		}
		

		static class CellValue {
			private SourceDirection sourceDirection;
			private double score;
			
			public CellValue(SourceDirection sourceDirection, double score) {
				if(sourceDirection == null){
					throw new IllegalArgumentException("sourceDirection should be not null");
				}
				
				this.sourceDirection = sourceDirection;
				this.score = score;
			}

			public SourceDirection getSourceDirection() {
				return sourceDirection;
			}

			public double getScore() {
				return score;
			}
			
			public String toString(){
				return Utils.format(score, 1) + "(" + sourceDirection + ")";
			}
		}

		static class SourceDirection{
			private ScoreMatrix source;
			private Direction direction;
			
			public SourceDirection(ScoreMatrix source, Direction direction) {
//				if(source == null){
//					throw new IllegalArgumentException("Source matrix should be not null");
//				}
//				if(direction == null){
//					throw new IllegalArgumentException("Direction should be not null");
//				}
				
				this.source = source;
				this.direction = direction;
			}

			
			public ScoreMatrix getSource() {
				return source;
			}

			public Direction getDirection() {
				return direction;
			}
			
			public String toString(){
				return source.getName() + ":" + direction;
			}
		}

	}
}
